package com.zycx.interceptor;


import com.zycx.common.annotation.IgnoreSecurity;
import com.zycx.common.constant.JWT.JWTConstants;
import com.zycx.system.user.entity.User;
import com.zycx.system.user.mapper.UserMapper;
import com.zycx.common.utils.StringMapUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Description:  根据 token 获取当前登录用户
 * Created by zycx on 2018-12-05 23:28
 * Created with IntelliJ IDEA.
 */
@Slf4j
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse httpServletResponse, Object handler) {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
       /* String requestPath = request.getRequestURI();
        log.info("requestPath: " + requestPath);
        if (requestPath.contains("/v2/api-docs") || requestPath.contains("/swagger") || requestPath.contains("/configuration/ui")) {
            return true;
        }
        if (requestPath.contains("/error")) {
            return true;
        } */
        if (method.isAnnotationPresent(IgnoreSecurity.class)) {
            return true;
        }

        //  获取请求消息头里面的 token
        String token = request.getHeader("Authorization");
        try {
            if (StringUtils.isEmpty(token)) {
                throw new Exception("无效token");
            }
            token = token.replace("%20", " ");
            if (token.startsWith(JWTConstants.Token_Request_Header)) {
                token = token.substring(JWTConstants.Token_Request_Header.length(), token.length()).replace(" ", "");
                JjwtCreateToken j = new JjwtCreateToken();
                Claims claims = j.parseJWT(token);
                Map<String, String> stringObjectMap = StringMapUtils.stringToMap(claims.getSubject());

                // 这里可以不用再去查询的, token 里面已经有这些信息了
                User user = userMapper.selectByPrimaryKey(stringObjectMap.get("id"));
                if (user == null) {
                    throw new RuntimeException("该用户不存在");
                }
                if ("1".equals(user.getStatus())) {
                    throw new RuntimeException("该用户已被冻结");
                }

                /* 通过 get/set 方法获取当前登录用户 */
                CurrentUser(stringObjectMap, token);
                /* 使用注解获取用户信息  两种方法,用其中一个就可以了*/
              //  currentSignInUser(request, stringObjectMap.get("id"));
            }
        } catch (ExpiredJwtException ex) {
            throw new RuntimeException("token过期");
        } catch (SignatureException ex) {
            throw new SignatureException("用户 token 签名错误!");
        } catch (IllegalArgumentException ex) {
            throw new IllegalArgumentException("用户 token 为空!");
        } catch (Exception e) {
            log.info("token错误:" + e.getMessage());
            throw new RuntimeException("用户 token 错误!");
        }
        return true;
    }

    /**
     * 通过注解获取当前登录用户信息
     *
     * @param request s
     * @param id      id
     */
    public void currentSignInUser(HttpServletRequest request, String id) {
        User userInfo = userMapper.selectByPrimaryKey(id);
        request.setAttribute("currentSignInUser", userInfo);
    }

    public void CurrentUser(Map<String, String> stringObjectMap, String token) {
        CurrentUser.setUserID(stringObjectMap.get("id"));
        CurrentUser.setName(stringObjectMap.get("name"));
        CurrentUser.setUsername(stringObjectMap.get("userName"));
        CurrentUser.setStatus(stringObjectMap.get("status"));
        CurrentUser.setSuperAdmin(stringObjectMap.get("superAdmin"));
        CurrentUser.setToken(token);
    }


}
